#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <string>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
const static int defaultfd=-1;
const static int defaultlisten=8;
class Server
{
public:
    Server(const uint16_t port)
    :listenfd(defaultfd)
    ,_port(port)
    {
    }
    ~Server()
    {
    }
    void server(int my_sockfd)
    {
        // 进行echoserver
        // 创建缓冲区：
        while (1)
        {
            char buffer[1024];
            int ret = read(my_sockfd, buffer, sizeof(buffer));
            if (ret < 0)
            {
                std::cout << "read fail!" << std::endl;
                close(my_sockfd);
                break;
            }
            else if (ret == 0)
            {
                // 说明客户端关闭了写入端
                std::cout << "client exit me too!" << std::endl;
                close(my_sockfd);
                break;
            }
            else
            {
                // 读成功了
                buffer[ret] = '0';
                std::cout << "client say:" << buffer << std::endl;
                std::string echomessager = "server say#";
                echomessager += buffer;
                int ret = write(my_sockfd, echomessager.c_str(), echomessager.size());
                (void)ret;
            }
        }
    }
    void Init()
    {
        int n = socket(AF_INET, SOCK_STREAM, 0);
        if (n < 0)
        {
            std::cout << "socket fail!" << std::endl;
        }
        listenfd = n;
        // 绑定ip与端口
        struct sockaddr_in local;
        local.sin_family = AF_INET;
        local.sin_port = _port;
        local.sin_addr.s_addr = INADDR_ANY;
        socklen_t len = sizeof(local);
        int ret = bind(listenfd, (const struct sockaddr *)&local, len);
        if (ret < 0)
        {
            std::cout << "bind fail!" << std::endl;
        }
        // 将套接字设置为监听：
        int s = listen(listenfd, defaultlisten);
        if (s < 0)
        {
            std::cout << "listen fail!" << std::endl;
        }
    }
    void Start()
    {
        while (1)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            // 当有客户端连接服务器时服务器单独为该用户创建套接字用于数据收发
            int sockfd = accept(listenfd, (struct sockaddr *)&peer, &len);
            if (sockfd < 0)
            {
                std::cout << "accept fail!" << std::endl;
                exit(2);
            }
            std::cout << "accept success!" << std::endl;
            server(sockfd);
        }
    }

private:
    int listenfd;
    uint16_t _port;
};
